/**
 *
 */
package com.angel.io.processors.runners.transformers.impl;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import com.angel.io.descriptor.ExportFileProcessorDescriptor;
import com.angel.io.descriptor.ExportedFileDescriptor;
import com.angel.io.exceptions.InvalidRowDataException;
import com.angel.io.exceptions.TransformerProcessorException;
import com.angel.io.factories.FileColumnsFactory;
import com.angel.io.processors.commands.exports.ExportFileProcessorCommand;
import com.angel.io.processors.commands.exports.ExportRowProcessorCommand;
import com.angel.io.processors.commands.imports.ImportFileProcessorCommand;
import com.angel.io.processors.commands.imports.ImportRowProcessorCommand;
import com.angel.io.processors.runners.exports.ExportProcessorRunner;
import com.angel.io.processors.runners.exports.impl.ExportFileProcessorRunner;
import com.angel.io.processors.runners.imports.ImportProcessorRunner;
import com.angel.io.processors.runners.imports.impl.ImportFileProcessorRunner;
import com.angel.io.processors.runners.transformers.TransformerProcessorRunner;

/**
 * @author William
 *
 */
public class FileTransformerProcessorRunner implements TransformerProcessorRunner{

	private static final Logger LOGGER = Logger.getLogger(FileTransformerProcessorRunner.class);

	private ImportProcessorRunner importProcessorRunner;
	
	private ExportProcessorRunner exportProcessorRunner;

	public FileTransformerProcessorRunner(){
		super();
	}
	
	public void setExportProcessorRunner(ExportFileProcessorDescriptor fileProcessorDescriptor, ExportRowProcessorCommand exportRowCommand, ExportFileProcessorCommand exportFileCommand){
		this.setExportProcessorRunner(new ExportFileProcessorRunner(fileProcessorDescriptor, exportRowCommand, exportFileCommand));
	}
	
	public void setImportProcessorRunner(ExportFileProcessorDescriptor fileProcessorDescriptor, ImportRowProcessorCommand importRowCommand, ImportFileProcessorCommand importFileCommand){
		this.setImportProcessorRunner(new ImportFileProcessorRunner(fileProcessorDescriptor, importFileCommand, importRowCommand));
	}
	
	public void addImportAlias(String columnName, String aliasName){
		this.getImportProcessorRunner().addAliasFor(columnName, aliasName);
	}
	
	public void addImportAlias(String columnName, List<String> aliasesName){
		this.getImportProcessorRunner().addAliasFor(columnName, aliasesName);
	}
	
	public void addExportColumn(String columnName, Integer position){
		this.getExportProcessorRunner().addColumn(columnName, position);
	}
	
	public void addExportColumns(FileColumnsFactory fileColumnsFactory){
		this.getExportProcessorRunner().addColumns(fileColumnsFactory);
	}
	
	public void addExportFirstColumn(String columnName){
		this.getExportProcessorRunner().addFirstColumn(columnName);
	}
	
	public void addExportNextColumn(String columnName){
		this.getExportProcessorRunner().addNextColumn(columnName);
	}
	
	public void addExportAlias(String columnName, String aliasName){
		this.getExportProcessorRunner().addAliasFor(columnName, aliasName);
	}
	
	public void addExportAlias(String columnName, List<String> aliasesName){
		this.getExportProcessorRunner().addAliasFor(columnName, aliasesName);
	}


	public ExportedFileDescriptor runProcess(InputStream inputStream, Integer... pages) throws InvalidRowDataException {
		long beginMillis = System.currentTimeMillis();
		LOGGER.info("Beginning transformer process at [" + new Date() + "].");
		List<?> _list = this.getImportProcessorRunner().runProcess(inputStream, pages);

		ExportedFileDescriptor exportedFileDescriptor = this.getExportProcessorRunner().runProcess(_list);
		long endMillis = System.currentTimeMillis();
		LOGGER.info("Ended transformer process at [" + new Date() + "]. It ended in [" + ((endMillis - beginMillis ) / 1000 ) + "] seconds.");
		return exportedFileDescriptor;
	}


	/**
	 * @return the importProcessorRunner
	 */
	protected ImportProcessorRunner getImportProcessorRunner() {
		if(this.importProcessorRunner == null){
			throw new TransformerProcessorException("Import processor runner cannot be null to [add columns | add alias | run transformer process].");
		}
		return importProcessorRunner;
	}


	/**
	 * @param importProcessorRunner the importProcessorRunner to set
	 */
	protected void setImportProcessorRunner(
			ImportProcessorRunner importProcessorRunner) {
		this.importProcessorRunner = importProcessorRunner;
	}


	/**
	 * @return the exportProcessorRunner
	 */
	protected ExportProcessorRunner getExportProcessorRunner() {
		if(this.exportProcessorRunner == null){
			throw new TransformerProcessorException("Export processor runner cannot be null to [add columns | add alias | run transformer process].");
		}
		return exportProcessorRunner;
	}


	/**
	 * @param exportProcessorRunner the exportProcessorRunner to set
	 */
	protected void setExportProcessorRunner(
			ExportProcessorRunner exportProcessorRunner) {
		this.exportProcessorRunner = exportProcessorRunner;
	}
}
